import json
import os.path
import threading
import re
import time
import hashlib
import requests
from .compBase import TBaseComp
class TWxApp:
    def __init__(self):
        self.code=""
        self.ak=""
        self.sk=""
        self.token=""
        self.ticket=""
        self.tokenTime =0
        self.localFn=""
        self.dataPath=""
        self.url_token="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={ak}&secret={sk}"
        self.url_ticket="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={token}&type=jsapi"
        self.url_openId="https://api.weixin.qq.com/sns/oauth2/access_token?appid={ak}&secret={sk}&code={code}&grant_type=authorization_code"
    def load(self):
        try:
            if os.path.exists(self.localFn):
                with open ( self.localFn , 'r', encoding='utf-8') as f:
                    try:
                        content = f.read()
                        tokenInfo = json.loads(content)
                        self.token = tokenInfo['token']
                        self.ticket = tokenInfo['ticket']
                        self.tokenTime = tokenInfo['tokenTime']
                    except Exception as err:
                        print(err)
        except Exception as er :
            print(er)
    def save(self):
        try:
            dirName = os.path.dirname(self.localFn)
            print('localFn',self.localFn)
            if not os.path.exists(dirName):
                os.makedirs(dirName , 0x777 )
            with open ( self.localFn , 'w', encoding='utf-8') as f:
                try:
                    info ={
                        "token": self.token ,
                        "ticket": self.ticket ,
                        "tokenTime": self.tokenTime
                    }
                    content = json.dumps(info)
                    f.write(content)
                except Exception as err:
                    print(err)
        except Exception as er :
            print(er)
    def updateToken(self):
        status = 0
        try:
            token = ""
            tokenTm = 0
            ticket = ""

            nowTm = time.time()
            ps ={
                "ak": self.ak,
                "sk": self.sk
            }
            tokenUrl = self.url_token.format(**ps)
            respToken = requests.get(tokenUrl)
            respResult = respToken.json()
            if 'access_token' in respResult.keys():
                token = respResult['access_token']
                psTicket={
                    "token": token
                }
                ticketUrl = self.url_ticket.format(**psTicket)
                respTicket = requests.get(ticketUrl)
                ticketResult = respTicket.json()
                if "ticket" in ticketResult.keys():
                    ticket = ticketResult['ticket']

                    self.token = token
                    self.ticket = ticket
                    self.tokenTime = nowTm
                    self.save()
                    status = 1
            else:
                print(f'get token fail.' , respResult)
        except Exception as er :
            print(er)
        return  status

    def getToken(self):
        res = {
            "status": 0,
            "token": "",
            "ticket": "",
            "time": 0
        }
        try:
            nowTm = time.time()
            dlt = nowTm - self.tokenTime
            if dlt>4800:
                self.updateToken()
            if self.ticket!='' and self.token!='':
                res["token"] = self.token
                res['ticket'] = self.ticket
                res['time'] = self.tokenTime
                res['svrTime'] = time.time()
                res['ak'] = self.ak
                res['status'] = 1
        except Exception as er:
            print(er)
        return res
    def getOpenId(self ,code):
        res = {
            "status": 0 ,
            "openid":""
        }
        try:
            ps={
                "ak":self.ak ,
                "sk": self.sk,
                "code": code
            }
            openIdUrl = self.url_openId.format(**ps)
            resp = requests.get(openIdUrl)
            print(resp.content)
            respJson = resp.json()
            if 'openid' in respJson.keys():
                res['openid'] = respJson['openid']
                res['status'] = 1
        except Exception as er:
            print(er)
        return  res
    def getJsConfig(self , url):
        res = {
            "status": 0 ,
            "error":"",
            "noice:":"",
            "timestamp":0
        }
        try:
            resToken = self.getToken()
            if resToken['status'] == 1:
                strFormat = "jsapi_ticket={ticket}&noncestr={noice}&timestamp={timestamp}&url={url}"
                tm = time.time()+8*3600
                noice = str(int(tm * 1000))
                timestamp = int(tm)
                ps={
                    "ticket": "sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg",
                    "noice": "Wm3WZYTPz0wzccnW",
                    "timestamp": 1414587457 ,
                    "url": "http://mp.weixin.qq.com?params=value"
                }
                ps = {
                    "ticket": resToken['ticket'],
                    "noice": noice,
                    "timestamp": timestamp ,
                    "url": url
                }
                signStr = strFormat.format(**ps)
                print(signStr)
                signature = hashlib.sha1(signStr.encode('utf-8')).hexdigest()
                print(signature)
                res={
                    "status": 1 ,
                    "error":"",
                    "result":{
                        "debug":False,
                        "appId" : self.ak,
                        "nonceStr": noice,
                        "timestamp":timestamp,
                        "signature" :signature,
                        "jsApiList":[]
                    }
                }
            else:
                res['status'] = -100;
                res['error'] ='get token/ticket fail.'
        except Exception as er:
            print(er)
        return  res
    def downloadImgs(self , sidList, imgPath='imgs'):
        res = {
            "status": 0
        }
        try:
            resToken = self.getToken()
            if resToken['status'] == 1:
                res['status']=1
                th = threading.Thread( target= self.downloadImgListAsync , daemon=True , args=( resToken['token'] , sidList , imgPath))
                th.start()
            else:
                res['status'] = -100;
                res['error'] ='get token/ticket fail.'
        except Exception as er:
            print(er)
        return  res
    def downloadImgListAsync(self , token , sidList , imgPath='imgs'):
        try:
            for sid in sidList:
                try:
                    url= "https://api.weixin.qq.com/cgi-bin/media/get?access_token="+token+"&media_id="+ sid
                    response = requests.get(url, stream=True)
                    response.raise_for_status()
                    save_path = os.path.join( self.dataPath , imgPath , sid+".jpg")
                    dirSave = os.path.dirname( save_path)
                    if not os.path.exists(dirSave):
                        os.makedirs(dirSave , 0x777)
                    #save_path = "D:/wxdata/imgs/"+ sid+".jpg"
                    with open(save_path, "wb") as file:
                        for chunk in response.iter_content(chunk_size=16384):  # 可调整块大小以优化性能
                            file.write(chunk)
                    print(f"download image :{url}==>{save_path}")
                except Exception as err:
                    print(err)
        except Exception as er:
            print(er)

class TCompWx(TBaseComp):
    def __init__(self):
        super().__init__()
        self.componentKey = 'wx'
        self.wxApps={}
        self.handlers['gettoken'] = self.getToken
        self.handlers['getopenid'] = self.getOpenId
        self.handlers['getjsconfig'] = self.getJsConfig
        self.handlers['downloadimgs'] = self.downloadImgs
    def getWxApp(self, appCode):
        res = None
        try:
            if appCode in self.wxApps.keys():
                res = self.wxApps[appCode]
            elif appCode in self.settings.keys():
                res = TWxApp()
                res.code = appCode
                res.ak = self.settings[appCode]['ak']
                res.sk = self.settings[appCode]['sk']
                res.dataPath = os.path.join(  self.settings[appCode]['localPath'] ,"datas", res.code)
                res.localFn = os.path.join( self.settings[appCode]['localPath'] , res.code+".txt")
                res.load()
                self.wxApps[appCode] = res
        except Exception as er:
            print(er)
        return res
    def getToken(self , appCode):
        res = {
            "status": 0 ,
            "token":"",
            "ticket":"",
            "time": 0
        }
        try:
            wxApp = self.getWxApp(appCode)
            if not wxApp== None:
                res = wxApp.getToken()
        except Exception as er:
            print(er)
        return  res
    def getOpenId(self , appCode, code):
        res = {
            "status": 0 ,
            "openid":""
        }
        try:
            wxApp = self.getWxApp(appCode)
            print(wxApp.code)
            if not wxApp== None:
                res = wxApp.getOpenId(code)
        except Exception as er:
            print(er)
        return  res
    def getJsConfig(self , appCode , url):
        res = {
            "status": 0 ,
            "openid":""
        }
        try:
            wxApp = self.getWxApp(appCode)
            if not wxApp== None:
                res = wxApp.getJsConfig(url)
        except Exception as er:
            print(er)
        return  res
    def downloadImgs(self , appCode , sidList,  imgPath='imgs'):
        res = {
            "status": 0
        }
        try:

            wxApp = self.getWxApp(appCode)
            if not wxApp== None:
                res = wxApp.downloadImgs(sidList,imgPath)
        except Exception as er:
            print(er)
        return  res


compWx = TCompWx()
compWx.regist()